
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#include "em_leds.h"

#include "os_timer.h"
#include "rtl876x_rcc.h"
#include "rtl876x_gpio.h"
#include "rtl876x_pinmux.h"
#include "rtl876x_tim.h"
#include "boards.h"

#include "xDLPS.h"

static bool is_leds_timer_started = false; 
static bool is_led_on = false;
void* ledsBlinkTimer = NULL;


static void gpios_config(void)
{
    #if 1 
    Pad_Config( LEDS_PWM_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH );
    
    Pinmux_Config( LEDS_PWM_PIN, LEDS_PWM_TIMER_PIN_PINMUX ); 
    
    RCC_PeriphClockCmd( APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE );
    
    
    #define PWM_HIGH_COUNT          (LEDS_PWM_CYCLE * 10 - 1)
    #define PWM_LOW_COUNT           (LEDS_PWM_CYCLE * 90 - 1)
    TIM_TimeBaseInitTypeDef timInitStruct;    
    
    TIM_StructInit( &timInitStruct );
    timInitStruct.TIM_PWM_En                = PWM_ENABLE;
    timInitStruct.TIM_SOURCE_DIV_En         = ENABLE;
    timInitStruct.TIM_SOURCE_DIV            = TIM_CLOCK_DIVIDER_40; //1Mhz 
    timInitStruct.TIM_Mode                  = TIM_Mode_UserDefine;
    timInitStruct.TIM_PWM_High_Count        = PWM_HIGH_COUNT;
    timInitStruct.TIM_PWM_Low_Count         = PWM_LOW_COUNT;
//    
    TIM_TimeBaseInit( LEDS_PWM_TIMER_NUM, &timInitStruct );
    TIM_Cmd( LEDS_PWM_TIMER_NUM, DISABLE );     
    #endif 
}

static void hr_blink_timer_timeout_handler(void* pvParameter)
{
    // 翻转
    if( is_led_on == false )
    {
        is_led_on = true;
        TIM_Cmd( LEDS_PWM_TIMER_NUM, ENABLE );
        xDLPS_set( DLPS_LEDS );
    }
    else 
    {
        is_led_on = false; 
        TIM_Cmd( LEDS_PWM_TIMER_NUM, DISABLE );
        xDLPS_reset( DLPS_LEDS );
    }
}

void em_leds_init(void)
{
    gpios_config();
    if( ledsBlinkTimer == NULL )
    {
        os_timer_create( &ledsBlinkTimer, "hrBlinkTimer", 0, 25, true, hr_blink_timer_timeout_handler );
    }
}

void em_leds_start(void)
{
    if( !is_leds_timer_started )
    {
        is_leds_timer_started = true; 
        xDLPS_set( DLPS_LEDS );
        TIM_Cmd( LEDS_PWM_TIMER_NUM, ENABLE );
        if( ledsBlinkTimer != NULL )
        {
            os_timer_start( &ledsBlinkTimer );
        }
    }
}

void em_leds_stop(void)
{
    if( is_leds_timer_started )
    {
        is_leds_timer_started = false ;

        TIM_Cmd( LEDS_PWM_TIMER_NUM, DISABLE );
        xDLPS_reset( DLPS_LEDS );

        if( ledsBlinkTimer != NULL )
        {
            os_timer_stop( &ledsBlinkTimer );
        }
    }
}

void em_leds_enter_dlps(void)
{
    Pad_Config( LEDS_PWM_PIN, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW ); 
}

void em_leds_exit_dlps(void)
{
    Pad_Config( LEDS_PWM_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW ); 
}
